#ifndef PROCESSO_H
#define	PROCESSO_H

#include <stdlib.h>

#ifdef	__cplusplus
extern "C" {
#endif
    
/**
 *   O processo e tabela de processo eh uma estrutura
 */
    
    struct item {
        int id;//recurso
        int contador;        
    };
    
    typedef struct item Item_recurso;
    
typedef struct{
    int id; //id de cada processo
    int quantum; //tempo que terá para execucao
    int contadorPrograma;//posicao do vetor na memoria
    int arquivoAberto;//depende do grupo de arquivos
    int estado; //0 - PROCESSO FINALIZADO  1- PRONTO 2- BLOQUEADO 3- EXECUCAO
    int prioridade; //0 - Núcleo | 1 - Usuário
    int quantidadeMemoriaAlocada;
}TabelaProcesso;


typedef struct{  
    int pid;                     //(ID do processo)                      - identificador do processo
    int prioridade;              //(prioridade)                          - 0-núcleo ; 1-usuário
    int instrucoes;              //(Instruções)                          - quantidade de instruções
    int entradasaida;            //(Entrada/Saída                        - ciclos de clock
    int regiaocritica;           //(Instruções da região crítica)        - quantidade de instruções
    int errofatal;               //(Erro fatal)                          - erro divisão por zero 0 - o programa nao tera erro faltal e 1 contera erro fatal
    int referenciamemoria;       //(Referência de memória)               - endereço referenciado na memória virtual
    int chamadasistema;          //(Chamada de sistema)                  - quantidade de instruções no processo do nucleo que trata da chamada ao sistema
    int tam_instrucoes_importantes;     //(Tamanho de instruções mais importantes do processo)       - importante para realizar paginação
    int instrucoes_importantes[200];        //(instruções mais importantes do processo)                  - importante para realizar paginação        
    int tam_instrucoes_menos_importantes;     //(Tamanho de instruções menos importantes do processo)       - importante para realizar paginação
    int instrucoes_menos_importantes[200];        //(instruções menos importantes do processo)                  - importante para realizar paginação            
    int recursos_necessarios[2];//define o recursos que o processo ira requisitar
    Item_recurso recursos_alocados[2];
    int recursos_indicador ;//estrutura auxiliar para recurso apenas
    TabelaProcesso *tabelaProcesso;
}Processo;

/**
 *
 * @param processo - sera impresso os dados do processo
 */
void imprimeProcesso(Processo processo);


/**
 * Abre um arquivo binario para leitura com o nome passado em parametro
 * @param nome_arquivo - nome do arquivo binario a ser aberto para leitura
 */
FILE* abreArquivoLeitura(char* nome_arquivo);

/**
 * Abre um arquivo binario para escrita com o nome passado em parametro
 * @param nome_arquivo - nome do arquivo binario a ser aberto para escrita
 */
FILE* abreArquivoEscrita(char* nome_arquivo);


/**
 *
 * @param file - ao chamar abreArquivoLeitura sera chamado instanciaProcesso que esta encarregada
 * de instanciar um processo p de acordo com os dados contidos em file
 */
void instanciaProcesso(FILE* file, Processo* p);

/**
 * Grava o processo em um arquivo BINARIO, ou seja, nao conseguimos entender os caracteres
 * que ele armazena, esta estrategia facilita na leitura de um processo(veja em instanciaProcesso). 
 * 
 * @param p e o processo a ser gravado em arquivo binario
 * @param file e o nome do arquivo binario
 */
void gravaProcesso(Processo* p, char* file );

/**
 * Fecha o arquivo passado por parametro
 * @param file
 */
void fechaArquivo(FILE* file);


/**
 * 
 * @param p
 * @param pid
 * @param prioridade
 * @param instrucoes
 * @param entradasaida
 * @param regiaocritica
 * @param errofatal
 * @param referenciamemoria
 * @param chamadasistema
 * @paramtam tam_instrucoes_importantes 
 * @param instrucoes_importantes
 * @param recursos necessarios sendo um vetor
 * Esta funcao e similar a um construtor em java
 */
void setProcesso(Processo* p, int pid, int prioridade, int instrucoes, int entradasaida, 
                int regiaocritica, int errofatal, int referenciamemoria, int chamadasistema, 
                int tam_instrucoes_importantes, int instrucoes_importantes[], int tam_instrucoes_menos_importantes,
                int instrucoes_menos_importantes[], int recursos_necessarios[]);



//void setTabelaProcesso(Processo*p, TabelaProcesso *tb);
/**
 * Funcao que sera a organizadora dos cabecalhos das escritas no arquivo de texto de saida.
 * indica de modo temporal quando um processo foi criado, escalonamento, acessou memoria, mudou de estado 
 * executou uma instrucao, entrou/saiu da fila de execucao, terminou, tempo de execucao, tempo de criacao/exclusao da thread.
 */
void execute_process_organizer();

/*
 *Funcão responsável por instanciar um processo cujo o nome está em nome_arquivo
 */
void criaProcesso(char* nome_arquivo, Processo* processo);


/**
 * Tabela de Processos - Sistemas Operacionais
 * --------------------------------------
 *
 * 1. estado do processo:
 *      1- Pronto
 *      2 - Bloqueado
 *      3 - Executando
 * 2. seu contador de programa: posicao do vetor de memoria
 * 3. alocação de memória: peso do arquivo
 * 4. estados de seus arquivos abertos:  Responsabilidade do grupo de arquivos por enquanto vai ser rancomico
 * 5. quantum: tempo definido para execucao
 *
 * @author Caio Thomas Oliveira 11011BSI209
 * @author Matheus Ferreira da Silva 11011BSI234
 * @author Leonardo Pimentel Ferreira	11011BSI223
 */

/**
 * Especificado pelo professor
 *  - stack(pilha): nao colocar
 *  - arquivo aberto: RESPONSABILIDADE DO GRUPO DE ARQUIVOS
 *  - contador de programa
 *  - estado: 1- Pronto | 2 - Bloqueado | 3 - Executando
 *  - quantidade de memoria alocada: quanto bytes do arquivo
 *  - quantum: quantidade de tempo (definido pelo escalonamento)
 *  - tipo: 0 nucleo - 1 usuario
 *
 * Observacoes:
 * Necessario modificar durante a execucao do processo
 * - contador de programa
 * - estado 1- Pronto | 2 - Bloqueado | 3 - Executando
 * - arquivoAbertos
 */

TabelaProcesso* tb_nova(Processo* processo, int arquivoAberto, int quantum, int qtdMemoriaAlocada);

/**
 * Imprime a tabela de processos
 */
void tb_imprime(TabelaProcesso* tp);

#ifdef	__cplusplus
}
#endif

#endif	/* PROCESSO_H */

